import * as PIXI from 'pixi.js';
import { Sprite, TilingSprite } from 'pixi.js';
import * as TWEEN from '@tweenjs/tween.js';
import { manifest } from "./config";

let PixiApp: PIXI.Application;
export default class PixiEngine {
    private tweens: TWEEN.Tween<any>[] = [];
    private cars: Sprite[] = [];
    private flames: Sprite[] = [];
    private background: TilingSprite;
    private backgroundBottom: TilingSprite;
    private finishLine: PIXI.Sprite;
    constructor(width: number, height: number) {
        this.init(width, height);
    }

    init = async (width: number, height: number) => {
        if (PixiApp) {
            PixiApp.destroy(true, { children: true, texture: true, baseTexture: true });
        }
        PixiApp = new PIXI.Application({ width, height, backgroundAlpha: 0 });

        // 更新动画
        PixiApp.ticker.add(() => {
            TWEEN.update();
        });

        await this.loadResource();
        this.initScene()
        // setTimeout(() => {
        //     this.startRace()
        // }, 1000)

        // setTimeout(() => {
        //     this.endRace([2, 0, 1, 3, 7, 5, 6, 4, 8, 9])
        // }, 5000)
    };

    loadResource = async () => {
        await PIXI.Assets.init({ manifest });
        await PIXI.Assets.loadBundle('pk10');
    };

    initScene = () => {
        // 初始化背景
        const bgTexture = PIXI.Texture.from('topbg');
        this.background = new PIXI.TilingSprite(bgTexture, PixiApp.screen.width * 2, bgTexture.height);
        this.background.position.set(0, 0);
        this.background.scale.set(0.5, 0.5);
        PixiApp.stage.addChild(this.background);
        const bgTextureBottom = PIXI.Texture.from('bottombg');
        this.backgroundBottom = new PIXI.TilingSprite(bgTextureBottom, PixiApp.screen.width * 2, bgTextureBottom.height);
        this.backgroundBottom.position.set(0, PixiApp.screen.height - bgTextureBottom.height / 2);
        this.backgroundBottom.scale.set(0.5, 0.5);
        PixiApp.stage.addChild(this.backgroundBottom);


        // 初始化终点线
        const finishLineTexture = PIXI.Texture.from('finishLine');
        this.finishLine = new PIXI.Sprite(finishLineTexture);
        this.finishLine.anchor.set(0.5);
        this.finishLine.scale.set(0.5); // 根据需要调整缩放
        this.finishLine.rotation =- Math.PI/2
        this.finishLine.position.set(-this.finishLine.width, PixiApp.screen.height / 2); // 初始位置在屏幕外
        this.finishLine.visible = false; // 初始不可见
        PixiApp.stage.addChild(this.finishLine);

        // this.background.anchor.set(0)
        // 初始化汽车
        const carSpacing = 10; // 汽车之间的间隔
        const marginVertical = 50; // 赛道上下留出的背景高度
        const availableHeight = PixiApp.screen.height - marginVertical * 2; // 可用于赛道的高度
        const trackHeight = (availableHeight - carSpacing * (10 - 1)) / 10; // 每条赛道的高度

        // for (let i = 0; i < 10; i++) {
        //     const car = new PIXI.Sprite(PIXI.Texture.from('car' + (i + 1)));
        //     const flame = new PIXI.Sprite(PIXI.Texture.from('flame'));
        //     // flame.anchor.set(0.5);
        //     // flame.scale.set(0.5);
        //     flame.position.set(car.width / 2, -car.height / 4);
        //     flame.visible = false;
        //     car.addChild(flame)
        //     this.flames.push(flame);
        //     car.anchor.set(0.5);
        //     car.scale.set(0.5); // 缩放小车宽高为原来的一半

        //     // 计算每辆车的y位置，使得它们之间有间隔，并且赛道上下有背景
        //     const carPositionY = marginVertical + i * (trackHeight + carSpacing) + trackHeight / 2;
        //     car.position.set(PixiApp.screen.width - car.width, carPositionY); // 将汽车放在右侧起点
        //     this.cars.push(car);
        //     PixiApp.stage.addChild(car);
        // }


    };

    startRace = () => {
        // // 背景循环滚动
        PixiApp.ticker.add(this.bgMove);
        // 汽车缓动动画
        this.cars.forEach((car, index) => {
            let previousX = car.position.x;

            const randomDelay = Math.random() * 1000; // 随机延迟时间
            const randomDuration = 2000 + Math.random() * 3000; // 随机动画持续时间
            const flame = this.flames[index];
            const tween = new TWEEN.Tween(car.position)
                .to({ x: PixiApp.screen.width / 2 }, randomDuration)
                .delay(randomDelay)
                .onStart(() => {
                    flame.visible = true; // 开始移动时显示火焰
                })
                .onStop(() => {
                    flame.visible = false; // 停止移动时隐藏火焰
                })
                .onComplete(() => {
                    flame.visible = false; // 完成移动时隐藏火焰
                })
                .onUpdate(() => {
                    if (car.position.x > previousX) {
                        flame.visible = false; // 向右移动时隐藏火焰
                    } else {
                        flame.visible = true; // 向左移动时显示火焰
                    }
                    previousX = car.position.x; // 更新前一个x位置
                })
                .yoyo(true) // 往返运动
                .repeat(Infinity) // 无限重复
                .start();

            this.tweens.push(tween);
        });
    };

    bgMove = () => {
        this.background.tilePosition.x -= 5;
        this.backgroundBottom.tilePosition.x -= 5;
    }

    // 控制每辆车前后到达的顺序
    endRace = (finishOrder: number[]) => {
        // 停止背景滚动
        PixiApp.ticker.remove(this.bgMove);

        // 停止所有缓动动画
        this.tweens.forEach(tween => {
            tween.stop();
            TWEEN.remove(tween);
        });
        this.tweens = [];

        // 计算终点位置
        const finishLineX = -this.cars[0].width / 2;


        this.finishLine.visible = true;
    
        // 创建缓动动画，从左到右移动终点线
        const tween = new TWEEN.Tween(this.finishLine.position)
            .to({ x: 60 }, 1000) // 假设动画持续时间为1000毫秒
            .easing(TWEEN.Easing.Quadratic.Out) // 设置缓动类型，例如二次方的缓出
            .onComplete(() => {
                // 动画完成后的回调函数（如果需要）
            })
            .start();


        // 创建新的缓动动画，根据传入的顺序数组来设置每辆车到达终点的时间
        finishOrder.forEach((lane, order) => {
            const car = this.cars[lane];
            const flame = this.flames[lane];
            const duration = 2000 + order * 500; // 根据顺序增加时间，确保按照指定顺序到达
            const tween = new TWEEN.Tween(car.position)
                .to({ x: finishLineX }, duration)
                .onComplete(() => {
                    flame.visible = false;
                    if (order === finishOrder.length - 1) {
                        // 最后一辆车到达终点后，重置所有车辆到起点
                        // this.resetCars();
                    }
                })
                .start();

            this.tweens.push(tween);
        });
    };

    destroy() {
        // 停止并移除所有缓动动画
        this.tweens.forEach(tween => {
            tween.stop();
            TWEEN.remove(tween);
        });
        this.tweens = []; // 清空缓动动画数组
        // 如果需要，销毁PIXI应用程序
        if (PixiApp) {
            PixiApp.destroy(true, {
                children: true, // 同时销毁子元素
                texture: true, // 销毁纹理
                baseTexture: true, // 销毁基础纹理
            });
            PixiApp = null; // 清除对应用程序的引用
        }
    }

    getCanvas() {
        return PixiApp.view;
    }
}